package com.jd.platform.gobrs.client.core.key.auto;

import com.jd.platform.gobrs.client.Context;
import com.jd.platform.gobrs.client.core.key.AbstractKeyBuilder;
import com.jd.platform.gobrs.client.core.key.KeyHandlerFactory;
import com.jd.platform.gobrs.client.etcd.EtcdConfig;
import com.jd.platform.gobrs.client.size.CacheSizeHolder;
import com.jd.platform.gobrs.common.model.GCacheKeyModel;
import com.jd.platform.gobrs.common.model.typeenum.CacheType;
import com.jd.platform.gobrs.common.model.typeenum.KeyType;
import com.jd.platform.gobrs.common.tool.Constant;
import com.jd.platform.gobrs.common.tool.HotKeyPathTool;

import java.util.concurrent.atomic.LongAdder;

/**
 * @program: gobrs
 * @ClassName AutoKeyPusher
 * @description:
 * @author: sizegang
 * @create: 2022-01-09 19:51
 * @Version 1.0
 **/
public class AutoKeyBuilder extends AbstractKeyBuilder {
    public void buildPrepareSend(String key, KeyType keyType, int count, boolean remove) {
        if (count <= 0) {
            count = 1;
        }
        if (key == null) {
            return;
        }

        if (keyType == null) {
            keyType = KeyType.GOBRS_KEY;
        }

        LongAdder adderCnt = new LongAdder();
        adderCnt.add(count);
        GCacheKeyModel hotKeyModel = new GCacheKeyModel();
        hotKeyModel.setAppName(Context.APP_NAME);
        hotKeyModel.setCacheType(CacheType.AUTO);
        hotKeyModel.setCount(adderCnt);
        hotKeyModel.setRemove(remove);
        hotKeyModel.setKeyType(keyType); // 必须 否则会被 worker 过滤器拦截
        hotKeyModel.setKey(key);
        hotKeyModel.setSize(CacheSizeHolder.cacheSize.get(key));

        if (remove) {
            // // TODO: 2022/1/9  
            //如果是删除key，就直接发到etcd去，不用做聚合。但是有点问题现在，这个删除只能删手工添加的key，不能删worker探测出来的
            //因为各个client都在监听手工添加的那个path，没监听自动探测的path。所以如果手工的那个path下，没有该key，那么是删除不了的。
            //删不了，就达不到集群监听删除事件的效果，怎么办呢？可以通过新增的方式，新增一个热key，然后删除它
            EtcdConfig.configCenter().putAndGrant(HotKeyPathTool.keyPath(hotKeyModel), Constant.DEFAULT_DELETE_VALUE, 1);
            EtcdConfig.configCenter().delete(HotKeyPathTool.keyPath(hotKeyModel));
            //也删worker探测的目录
            EtcdConfig.configCenter().delete(HotKeyPathTool.keyRecordPath(hotKeyModel));
        } else {
            // 直接将访问的key 推送到worker端
            KeyHandlerFactory.getCollector().collect(hotKeyModel);
        }
    }

    public void buildPrepareSend(String key, KeyType keyType, int count) {
        buildPrepareSend(key, keyType, count, false);
    }

    public void buildPrepareSend(String key, KeyType keyType) {
        buildPrepareSend(key, keyType, 1, false);
    }

    public void buildPrepareSend(String key) {
        buildPrepareSend(key, KeyType.GOBRS_KEY, 1, false);
    }

    public void remove(String key) {
        buildPrepareSend(key, KeyType.GOBRS_KEY, 1, true);
    }
}
